package com.ruoyi.web.controller.api;


import com.ruoyi.cat.domain.CatActivityTable;
import com.ruoyi.cat.domain.CatShareuserTable;
import com.ruoyi.cat.domain.DTO.ArticletaskDTO;
import com.ruoyi.cat.domain.VO.CatForward;
import com.ruoyi.cat.service.*;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;


import cn.hutool.core.net.URLDecoder;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.cat.domain.CatArticletaskTable;
import com.ruoyi.cat.domain.CatOutsiderealmTable;
import com.ruoyi.cat.domain.DTO.AppIdDTO;
import com.ruoyi.cat.domain.VO.AppIdVO;
import com.ruoyi.cat.domain.VO.CatIpCodeVO;
import com.ruoyi.cat.domain.VO.WritingsVO;
import com.ruoyi.cat.service.impl.RichTextService;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.IpRegion;
import com.ruoyi.common.utils.OrderUtil;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.Base64Util;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Api(tags = "api-外连接使用获取详情接口")
@RestController
@RequestMapping("/api/writings")
public class WritingsController  extends BaseController {

    @Autowired
    private ICatArticletaskTableService catArticletaskTableService;

    @Autowired
    private ICatActivityTableService iCatActivityTableService;

    @Autowired
    private RichTextService richTextService;

    @Autowired
    private ICatIprecordTableService catIprecordTableService;

    @Autowired
    private ICatOutsiderealmTableService iCatOutsiderealmTableService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ICatShareuserTableService iCatShareuserTableService;


    // Redis中token的key前缀
    private static final String TOKEN_KEY_PREFIX = "weixin:access_token:";
    // token有效期为7200秒(2小时)，我们可以提前5分钟刷新
    private static  Integer EXPIRE_SECONDS = 7200;

    private static final long REFRESH_BEFORE_EXPIRE = 300;

    @ApiOperation("api-获取文章富文本页面")
    @GetMapping("getArticle/{id}")
    public ResponseEntity<String> generateVirtualPage(HttpServletRequest request,@PathVariable String id) {
        try {
            String articleId = Base64Util.decryptNumber(id);
            //访问哟啊记录用户的ip等信息
            String domain = request.getServerName();
            System.out.println("域名------- "+domain);
            System.out.println(IpUtils.getHostIp());
            String htmlContent = richTextService.generateVirtualPage(Long.parseLong(articleId));
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.TEXT_HTML);
          /*  CatArticletaskTable richText = catArticletaskTableService.selectCatArticletaskTableById(Long.parseLong(articleId));
            // 生成HTML文件
            try {
                // 1. 读取模板文件
                // 使用 ClassPathResource 来获取模板文件
                Resource resource = new ClassPathResource("templates/link.html");
                String template = IOUtils.toString(resource.getInputStream(), StandardCharsets.UTF_8);

                // 替换文章内容
                String articleContent = richText.getArticleContent();
                String modifiedHtml = template.replace(
                        "<div id=\"content\"></div>",
                        "<div id=\"content\">" + articleContent + "</div>"
                );

                // 使用系统无关的路径生成方式
                String baseDir = "D:\\java\\";  // 获取用户主目录
                Path outputDir = Paths.get(baseDir, "article_output");  // 创建输出目录
                if (!Files.exists(outputDir)) {
                    Files.createDirectories(outputDir);
                }

                String fileName = "article_" + articleId + ".html";
                Path filePath = outputDir.resolve(fileName);
                Files.write(filePath, modifiedHtml.getBytes(StandardCharsets.UTF_8));

                // 4. 可选：将文件路径保存到数据库
               // catArticletaskTable.setHtmlPath(filePath);
               // catArticletaskTableMapper.updateHtmlPath(catArticletaskTable);

            } catch (Exception e) {
                // 处理异常
              //  log.error("Failed to generate HTML file", e);
                throw new RuntimeException("Failed to generate HTML file", e);
            }*/
            return new ResponseEntity<>(htmlContent, headers, HttpStatus.OK);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("页面生成失败");
        }
    }

    @ApiOperation("api-获取文章详情")
    @GetMapping("getArticleDetails")
    public AjaxResult getArticleDetails(HttpServletRequest request,String id,String domainUrl) {
        // 先尝试从Redis获取缓存
//        Object cachedArticle = redisCache.getCacheObject("Article_"+id);
//        if (cachedArticle != null) {
//            return success((ArticletaskDTO) cachedArticle);
//        }
        String articleId = Base64Util.decryptNumber(id);

        System.out.println(" ----------  "+domainUrl);
        String domain = request.getServerName();
        System.out.println("域名 -----  "+domain);
        ArticletaskDTO articletaskDTO = catArticletaskTableService.selectCatArticletaskById(Long.parseLong(articleId));
        if (articletaskDTO != null) {
            if (StringUtils.isNotEmpty(articletaskDTO.getDisplayPeople())&&
                    articletaskDTO.getDisplayPeople().equals("1")){
                articletaskDTO.setQuantity(articletaskDTO.getNumberVisitors());
            }
            // 将查询结果存入Redis缓存,设置1分钟过期
            redisCache.setCacheObject("Article_"+id, articletaskDTO, 40, TimeUnit.SECONDS);
        }
        return success(articletaskDTO);
    }

    public static void main(String[] args) {

        String articleId1 = URLDecoder.decode("AAAA", StandardCharsets.UTF_8);

        System.out.println("articleId1----->"+articleId1);

        String articleId = Base64Util.encryptNumber("10");
        System.out.println("articleId1----->"+articleId);

        System.out.println(articleId);
    }

    @ApiOperation("api-新增活动阅读量和人数")
    @PostMapping("inputArticleReadNum")
    public AjaxResult inputReadNum(HttpServletRequest request, @RequestBody WritingsVO readNumVO) {
        String ipAddress1 = IpUtils.getIpAddr(request);
        System.out.println("ipAddress1----->"+ipAddress1);
        String articleId = Base64Util.decryptNumber(readNumVO.getId());
        CatIpCodeVO codeVO = new CatIpCodeVO();
        codeVO.setActivityId(Long.parseLong(articleId));
        String ipAddress = IpUtils.getHostIp();
        System.out.println("ipAddress2----->"+ipAddress);
        codeVO.setIpCode(ipAddress1);
        IpRegion currentArea = IpAddressUtil.parseIpLocation(ipAddress1);
        //String currentArea2 = IpAddressUtil.getIpAddressByOnline(ipAddress1);
       // System.out.println("currentArea----->"+currentArea2);
        String currentArea3 = IpAddressUtil.getCityInfoByMemorySearch(ipAddress1);
        System.out.println("currentArea3----->"+currentArea3);
        if (currentArea != null) {
            codeVO.setCity(currentArea.getCity());
        }
        CatArticletaskTable catArticletaskTable = catArticletaskTableService.selectCatArticletaskTableById(Long.parseLong(articleId));

        Integer i = catIprecordTableService.insertCatIpCodeUnique(codeVO);
        if (i > 0) {
            System.out.println("新增成功");
            //大于0的时候 新增人员
            if (catArticletaskTable != null) {
                if (catArticletaskTable.getNumberVisitors() != null) {
                    catArticletaskTable.setNumberVisitors(catArticletaskTable.getNumberVisitors() + 1);
                }else{
                    catArticletaskTable.setNumberVisitors(1L);
                }
            }
        }
        if (catArticletaskTable != null) {
            if(catArticletaskTable.getQuantity() != null){
                catArticletaskTable.setQuantity(catArticletaskTable.getQuantity() + 1);
            }else{
                catArticletaskTable.setQuantity(1L);
            }
            return success(catArticletaskTableService.updateTable(catArticletaskTable));
        }
        return success();
    }

    @ApiOperation("api-转发和分享")
    @PostMapping("forwardShare")
    public AjaxResult forwardShare(HttpServletRequest request, @RequestBody WritingsVO readNumVO) {
    /*    if (!Base64Util.isBase64Encrypted(readNumVO.getId())) {
            return error("id不是加密字段");
        }*/

        System.out.println("转发和分享---->"+readNumVO.getId());
        String articleId = URLDecoder.decode(readNumVO.getId(), StandardCharsets.UTF_8);
        articleId = Base64Util.decryptNumber(articleId);
        System.out.println("转发和分享---->"+articleId);
        CatArticletaskTable catArticletaskTable = new CatArticletaskTable();
        CatArticletaskTable catArticletaskTable1 = catArticletaskTableService.selectCatArticletaskTableById(Long.parseLong(articleId));
        catArticletaskTable.setId(Long.parseLong(articleId));
        CatShareuserTable catShareuserTable = new CatShareuserTable();
        catShareuserTable.setUserId(readNumVO.getRecommendId());
        catShareuserTable.setArticleId(Long.parseLong(articleId));
        catShareuserTable.setType("1");
        CatShareuserTable catShareuserTable1 = iCatShareuserTableService.getShareUser(catShareuserTable);
        if (catShareuserTable1 == null) {
            catShareuserTable.setQuantity(1L);
            catShareuserTable.setUserId(readNumVO.getRecommendId());
            catShareuserTable.setArticleId(Long.parseLong(articleId));
            catShareuserTable.setType("1");
            iCatShareuserTableService.insertCatShareuserTable(catShareuserTable);
        }else{
            catShareuserTable1.setQuantity(catShareuserTable1.getQuantity() + 1);
            iCatShareuserTableService.updateCatShareuserTable(catShareuserTable1);
        }
        if (catArticletaskTable1.getForwardNum() != null) {
            catArticletaskTable.setForwardNum(catArticletaskTable1.getForwardNum() + 1);
        }else{
            catArticletaskTable.setForwardNum(1L);
        }
        if (readNumVO.getRecommendId() != null) {
            CatForward catForward = new CatForward();
            catForward.setUserId(readNumVO.getRecommendId());
            catForward.setArticleId(Long.parseLong(articleId));
            catForward.setType("1");
            catIprecordTableService.saveArticleData(catForward);
        }
       // catArticletaskTable.setForwardNum(readNumVO.getId());
        return success(catArticletaskTableService.updateTable(catArticletaskTable));
    }


    @ApiOperation("api-活动转发和分享")
    @PostMapping("articleShare")
    public AjaxResult articleShare(HttpServletRequest request, @RequestBody WritingsVO readNumVO) {
    /*    if (!Base64Util.isBase64Encrypted(readNumVO.getId())) {
            return error("id不是加密字段");
        }*/

        log.info("articleShare活动转发和分享---->"+readNumVO);
        System.out.println("articleShare活动转发和分享---->"+readNumVO.getId());
        String articleId = URLDecoder.decode(readNumVO.getId(), StandardCharsets.UTF_8);
        articleId = Base64Util.decryptNumber(articleId);
        System.out.println("articleShare活动转发和分享---->"+articleId);
        CatActivityTable catArticletaskTable = new CatActivityTable();
        CatActivityTable catArticletaskTable1 = iCatActivityTableService.selectCatActivityTableById(Long.parseLong(articleId));
        catArticletaskTable.setId(Long.parseLong(articleId));
        if (catArticletaskTable1.getActivityForwardNum() != null) {
            catArticletaskTable.setActivityForwardNum(catArticletaskTable1.getActivityForwardNum() + 1);
        }else{
            catArticletaskTable.setActivityForwardNum(1L);
        }
        CatShareuserTable catShareuserTable = new CatShareuserTable();
        catShareuserTable.setUserId(readNumVO.getRecommendId());
        catShareuserTable.setArticleId(Long.parseLong(articleId));
        catShareuserTable.setType("2");
        CatShareuserTable catShareuserTable1 = iCatShareuserTableService.getShareUser(catShareuserTable);
        if (catShareuserTable1 == null) {
            catShareuserTable.setQuantity(1L);
            catShareuserTable.setUserId(readNumVO.getRecommendId());
            catShareuserTable.setArticleId(Long.parseLong(articleId));
            catShareuserTable.setType("2");
            iCatShareuserTableService.insertCatShareuserTable(catShareuserTable);
        }else{
            catShareuserTable1.setQuantity(catShareuserTable1.getQuantity() + 1);
            iCatShareuserTableService.updateCatShareuserTable(catShareuserTable1);
        }
        if (readNumVO.getRecommendId() != null) {
            CatForward catForward = new CatForward();
            catForward.setUserId(readNumVO.getRecommendId());
            catForward.setArticleId(Long.parseLong(articleId));
            catForward.setType("2");
            catIprecordTableService.saveArticleData(catForward);
        }
        // catArticletaskTable.setForwardNum(readNumVO.getId());
        return success(iCatActivityTableService.updateCatActivity(catArticletaskTable));
    }




    @ApiOperation("api-根据加密id获取appid和秘钥")
    @PostMapping("getAppId")
    public AjaxResult getAppId(HttpServletRequest request,@RequestBody AppIdVO appIdVO) {
        String id = appIdVO.getId();
        String url = appIdVO.getUrl();
        String decodedUrl = URLDecoder.decode(url, StandardCharsets.UTF_8);
        id = URLDecoder.decode(id, StandardCharsets.UTF_8);
        System.out.println("url---->"+url);
        System.out.println("url---->"+decodedUrl);
        System.out.println("id---->"+id);
        if (!Base64Util.isBase64Encrypted(id)) {
            return error("id不是加密字段");
        }
        String articleId = Base64Util.decryptNumber(id);
        AppIdDTO appIdDTO = new AppIdDTO();
        CatArticletaskTable catArticletaskTable1 = catArticletaskTableService.selectCatArticletaskTableById(Long.parseLong(articleId));
        if (catArticletaskTable1 != null) {
            if (catArticletaskTable1.getDomainName() != null) {
                CatOutsiderealmTable catOutsiderealmTable = iCatOutsiderealmTableService.selectCatOutsiderealmByDomain(catArticletaskTable1.getDomainName());
                if (catOutsiderealmTable != null) {
                    if (catOutsiderealmTable.getAppId() != null && catOutsiderealmTable.getAppSecret() != null) {
                        appIdDTO.setAppId(catOutsiderealmTable.getAppId());
                        String timeStamp = OrderUtil.timestamp10();
                        String nonceStr = RandomStringUtils.randomAlphanumeric(32);
                        appIdDTO.setAppSecret(catOutsiderealmTable.getAppSecret());
                        appIdDTO.setTimeStamp(timeStamp);
                        appIdDTO.setNonceStr(nonceStr);
                        Map<String, String> wxPayMap = new HashMap<>();
                        wxPayMap.put("appId", appIdDTO.getAppId());
                       // wxPayMap.put("appSecret", appIdDTO.getAppSecret());
                        wxPayMap.put("timeStamp",timeStamp);
                        wxPayMap.put("nonceStr",nonceStr);
                        String sign = "";
                        try {
                           String token = getAccessToken(appIdDTO.getAppId(),appIdDTO.getAppSecret());
                           System.out.println("0000000000000000---->"+token);
                            String jsapiTicket = getJsapiTicket(token);
                            System.out.println("0000000000000000---->"+jsapiTicket);
                            String str = "jsapi_ticket=" + jsapiTicket +
                                "&noncestr=" + nonceStr +
                                "&timestamp=" + timeStamp +
                                "&url=" + decodedUrl;

                        // SHA1签名
                         String signature = DigestUtils.sha1Hex(str);
                         appIdDTO.setSign(signature);
                           // sign = WXPayUtil.generateSignature(wxPayMap, catOutsiderealmTable.getAppSecret(), WXPayConstants.SignType.HMACSHA256);
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    }else{
                        return error("未配置appid");
                    }
                }
            }else{
                return error("文章未配置域名");
            }
        }
        return success(appIdDTO);
    }


    // 生成签名配置
//    public Map<String, String> createJsapiSignature(String url) {
//        String accessToken = getAccessToken();
//        String jsapiTicket = getJsapiTicket(accessToken);
//
//        String nonceStr = UUID.randomUUID().toString();
//        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
//
//        // 参数字典序排序
//        String str = "jsapi_ticket=" + jsapiTicket +
//                "&noncestr=" + nonceStr +
//                "&timestamp=" + timestamp +
//                "&url=" + url;
//
//        // SHA1签名
//        String signature = DigestUtils.sha1Hex(str);
//
//        Map<String, String> map = new HashMap<>();
//        map.put("appId", appId);
//        map.put("timestamp", timestamp);
//        map.put("nonceStr", nonceStr);
//        map.put("signature", signature);
//        return map;
//    }


    // 获取 access_token
 /*   public String getAccessToken(String appId, String appSecret) {
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
                + appId + "&secret=" + appSecret;
        String result = HttpUtil.get(url);
        System.out.println("微信token------------->"+result);
        JSONObject json = JSONObject.parseObject(result);
        return json.getString("access_token");
    }*/


    public String getAccessToken(String appId, String appSecret) {
        String redisKey = TOKEN_KEY_PREFIX + appId;

        // 从缓存获取token
        String accessToken = redisCache.getCacheObject(redisKey);
        if (StringUtils.isNotEmpty(accessToken)) {
            // 获取剩余过期时间
            Long expire = redisCache.getExpire(redisKey);
            // 如果token存在且未到提前刷新时间，直接返回
            if (expire != null && expire > REFRESH_BEFORE_EXPIRE) {
                return accessToken;
            }
        }

        // 缓存中不存在或即将过期，重新获取
        synchronized (this.getClass()) {
            // 双重检查
            accessToken = redisCache.getCacheObject(redisKey);
            if (StringUtils.isNotEmpty(accessToken)) {
                Long expire = redisCache.getExpire(redisKey);
                if (expire != null && expire > REFRESH_BEFORE_EXPIRE) {
                    return accessToken;
                }
            }

            try {
                String newToken = getStableAccessToken(appId, appSecret);
                if (StringUtils.isNotEmpty(newToken)) {
                    // 存入缓存并设置过期时间
                    redisCache.setCacheObject(redisKey, newToken, EXPIRE_SECONDS, TimeUnit.SECONDS);
                    return newToken;
                }
            } catch (Exception e) {
                log.error("获取微信access_token失败", e);
                // 如果获取新token失败但缓存中还有旧token，返回旧token
                if (StringUtils.isNotEmpty(accessToken)) {
                    return accessToken;
                }
                throw new RuntimeException("获取微信access_token失败", e);
            }
        }
        return null;
    }

    private String getStableAccessToken(String appId, String appSecret) {
        String url = "https://api.weixin.qq.com/cgi-bin/stable_token";

        JSONObject requestBody = new JSONObject();
        requestBody.put("grant_type", "client_credential");
        requestBody.put("appid", appId);
        requestBody.put("secret", appSecret);

        String result = HttpUtil.post(url, requestBody.toString());
        log.info("微信stable token响应------------->"+result);

        JSONObject json = JSONObject.parseObject(result);
        if (json.containsKey("access_token")) {
            return json.getString("access_token");
        }

        throw new RuntimeException("获取access_token失败: " + result);
    }

/*    private String getStableAccessToken(String appId, String appSecret) {
        String url = "https://api.weixin.qq.com/cgi-bin/stable_token";

        JSONObject requestBody = new JSONObject();
        requestBody.put("grant_type", "client_credential");
        requestBody.put("appid", appId);
        requestBody.put("secret", appSecret);

        String result = HttpUtil.post(url, requestBody.toString());
        log.info("微信stable token响应------------->"+result);

        JSONObject json = JSONObject.parseObject(result);
        if (json.containsKey("access_token")) {
            return json.getString("access_token");
        }

        throw new RuntimeException("获取access_token失败: " + result);
    }*/

    // 获取 jsapi_ticket
    public String getJsapiTicket(String accessToken) {
        String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="
                + accessToken + "&type=jsapi";
        String result = HttpUtil.get(url);
        System.out.println("微信jsapi_ticket------------->"+result);
        JSONObject json = JSONObject.parseObject(result);
        return json.getString("ticket");
    }


    @ApiOperation("api-获取ip地址接口")
    @GetMapping("getIpCode")
    public AjaxResult getIpCode(HttpServletRequest request) {
        String ipAddress = IpUtils.getIpAddr(request);
       // System.out.println("获取ip地址接口   ==== "+ipAddress);
        IpRegion currentArea = IpAddressUtil.parseIpLocation(ipAddress);
        IpRegion currentArea1 = IpAddressUtil.parseIpLocation("120.225.52.111");
        System.out.println("获取ip地址接口1   ==== "+currentArea1.toString());
        System.out.println("获取ip地址接口 2  ==== "+currentArea.toString());

        String currentArea2 = IpAddressUtil.getIpAddressByOnline(ipAddress);
        System.out.println("currentArea2----->"+currentArea2);
       // String currentArea3 = IpAddressUtil.getCityInfoByMemorySearch(ipAddress);
        //System.out.println("currentArea3----->"+currentArea3);
        Map<String, Object> map = new HashMap<>();
        map.put("ipAddress", ipAddress);
        return success(map);
    }

/*    public static void main(String[] args) {
        System.out.println(IpAddressUtil.parseIpLocation("120.225.52.111"));
    }*/


}
